﻿using System;
using Microsoft.Xna.Framework;
using RainEngine.SceneManagement;

namespace RainEngine.SceneNodes.UI
{
    /// <summary>
    /// 滑动条抽象基类，水平滑动条和竖直滑动条从这个类继承。
    /// </summary>
    public abstract class UISliderBase:UISceneNode
    {
        #region 成员变量和构造函数

        //默认值
        protected static readonly Vector2 DefaultSliderRailSize = new Vector2(150, 4);
        protected static readonly Vector2 DefaultSliderButtonSize = new Vector2(24, 24);      
        protected static readonly Rectangle DefaultSliderRailRect = new Rectangle(1, 205, 91, 6);
        protected static readonly Rectangle DefaultSliderButtonRect = new Rectangle(152, 194, 40, 40);

        /// <summary>
        /// 滑块位置
        /// </summary>
        protected Vector2 sliderButtonPosition;        

        /// <summary>
        /// 滑块大小，默认大小24*24
        /// </summary>
        protected Vector2 sliderButtonSize;

        /// <summary>
        /// 滑块图像初始矩形
        /// </summary>
        protected Rectangle sliderButtonRectOrigin;

        /// <summary>
        /// 滑块图像高亮状态矩形
        /// </summary>
        protected Rectangle sliderButtonRectHighlight;

        /// <summary>
        /// 滑块图像点击状态矩形
        /// </summary>
        protected Rectangle sliderButtonRectClicked;

        /// <summary>
        /// 滑动条轨道位置
        /// </summary>
        protected Vector2 sliderRailPosition;
        
        /// <summary>
        /// 滑动条轨道大小，默认大小150*4
        /// </summary>
        protected Vector2 sliderRailSize;

        /// <summary>
        /// 滑动条轨道图像矩形
        /// </summary>
        protected Rectangle sliderRailRect;           

        /// <summary>
        /// 滑动条的最小值，默认为0
        /// </summary>
        protected float minValue = 0;

        /// <summary>
        /// 滑动条的最大值，默认为1
        /// </summary>
        protected float maxValue = 1.0f;

        /// <summary>
        /// 步进频率，默认为10，即从最小值到最大值需要移动10次
        /// </summary>
        protected int tickFrequency = 10;        

        /// <summary>
        /// 滑动条的值，默认为0
        /// </summary>
        protected float value = 0;

        /// <summary>
        /// 是否处在滑动状态
        /// </summary>
        protected bool isSliding = false;

        /// <summary>
        /// 创建一个滑动条基类
        /// </summary>
        /// <param name="engine">引擎</param>
        /// <param name="setScene">所属场景</param>
        /// <param name="setPosition">2D屏幕位置</param>
        /// <param name="setTextureName">使用的纹理名称</param>
        /// <param name="setSliderRailSize">轨道大小</param>
        /// <param name="setSliderRailRect">轨道图像矩形</param>
        /// <param name="setSliderButtonSize">滑块大小</param>
        /// <param name="setSliderButtonRectOrigin">滑块普通状态矩形</param>
        /// <param name="setSliderButtonRectHighlight">滑块高亮状态矩形</param>
        /// <param name="setSliderButtonRectClicked">滑块点击状态矩形</param>
        internal UISliderBase(RainGE engine, Scene setScene, Vector2 setPosition, string setTextureName, Vector2 setSliderRailSize, Rectangle setSliderRailRect, Vector2 setSliderButtonSize, Rectangle setSliderButtonRectOrigin, Rectangle setSliderButtonRectHighlight, Rectangle setSliderButtonRectClicked,bool useResource)
            : base(engine, setScene, setPosition, setTextureName,useResource)
        {
            this.sliderRailSize = setSliderRailSize;
            this.sliderRailRect = setSliderRailRect;
            this.sliderButtonSize = setSliderButtonSize;
            this.sliderButtonRectOrigin = setSliderButtonRectOrigin;
            this.sliderButtonRectHighlight = setSliderButtonRectHighlight;
            this.sliderButtonRectClicked = setSliderButtonRectClicked;
            //设置滑动条的大小
            ResetSize();
        }

        #endregion

        #region 属性

        /// <summary>
        /// 获取或设置滑块大小，滑块大小发生变化时需要重新计算滑动条的大小
        /// </summary>
        public Vector2 SliderButtonSize
        {
            get { return sliderButtonSize; }
            set
            {
                sliderButtonSize = value;
                ResetSize();
            }
        }

        /// <summary>
        /// 获取或设置滑块图像初始矩形
        /// </summary>
        public Rectangle SlideButtonRectOrigin
        {
            get { return sliderButtonRectOrigin; }
            set { sliderButtonRectOrigin = value; }
        }

        /// <summary>
        /// 获取或设置滑块图像高亮状态矩形
        /// </summary>
        public Rectangle SlideButtonRectHighlight
        {
            get { return sliderButtonRectHighlight; }
            set { sliderButtonRectHighlight = value; }
        }

        /// <summary>
        /// 获取或设置滑块图像点击状态矩形
        /// </summary>
        public Rectangle SlideButtonRectClicked
        {
            get { return sliderButtonRectClicked; }
            set { sliderButtonRectClicked = value; }
        }

        /// <summary>
        /// 获取或设置滑动条轨道大小，滑动条轨道大小发生变化时需要重新计算滑动条的大小
        /// </summary>
        public Vector2 SliderRailSize
        {
            get { return sliderRailSize; }
            set
            {
                sliderRailSize = value;
                ResetSize();              
            }
        }

        /// <summary>
        /// 获取或设置滑动条轨道图像矩形
        /// </summary>
        public Rectangle SlidreRailRect
        {
            get { return sliderRailRect; }
            set { sliderRailRect = value; }
        }

        /// <summary>
        /// 获取或设置步进频率，默认为10，即从最小值到最大值需要移动10次
        /// </summary>
        public int TickFrequency
        {
            get { return tickFrequency; }
            set
            {
                tickFrequency = value;
                ResetSliderButtonPosition();
            }
        }

        /// <summary>
        /// 获取或设置滑动条的最小值，minValue的值改变时需要重新设置滑块的位置
        /// </summary>
        public float MinValue
        {
            get { return minValue; }
            set
            {
                if (value > maxValue)
                    return;
                minValue = value;
                ResetSliderButtonPosition();
            }
        }

        /// <summary>
        /// 获取或设置滑动条的最大值，maxValue的值改变时需要重新设置滑块的位置
        /// </summary>
        public float MaxValue
        {
            get { return maxValue; }
            set
            {
                if (value  < minValue)
                    return;
                maxValue = value;                
                ResetSliderButtonPosition();
            }
        }

        /// <summary>
        /// 获取或设置滑动条的值，滑动条的值发生改变时引发ValueChanged事件。
        /// </summary>
        public float Value
        {
            get { return value; }
            set
            {
                this.value = value;
                OnValueChanged();
            }
        }

        #endregion  
      
        #region 事件相关处理程序

        /// <summary>
        /// 滑动条的值变化时引发的事件
        /// </summary>
        public event EventHandler ValueChanged;

        /// <summary>
        /// ValueChanged事件的处理程序，需要重新调整滑块的位置。
        /// OnValueChanged方法允许继承的类处理这个事件。
        /// 注意：当在继承类中覆写OnValueChanged时，一定要调用基类的OnValueChanged方法才可以注册委托
        /// </summary>        
        protected virtual void OnValueChanged()
        {
            if (ValueChanged != null)
                ValueChanged(this.value, null);
            if (value > maxValue)
                this.value = maxValue;
            if (value < minValue)
                this.value = minValue;
            ResetSliderButtonPosition();
        }

        /// <summary>
        /// 滑动条位置变化时的处理程序，需要重新调整滑块的位置
        /// </summary>
        protected override void OnLocationChanged()
        {
            base.OnLocationChanged();
            ResetSliderButtonPosition();
        }        

        /// <summary>
        /// 重新设置滑动条大小
        /// </summary>
        protected virtual void ResetSize()
        { }

        /// <summary>
        ///  重置滑块的位置
        /// </summary>
        protected virtual void ResetSliderButtonPosition()
        { }


        #endregion
    }
}